package net.chrone.quickpayapi;

import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.Map;

import org.springframework.util.Base64Utils;

public class SignatureUtil {

	private static String RSA = "RSA";

	/**
	 * 拼明文串
	 * @param map
	 * @return
	 */
	public static String assmeblyPlainText(Map<String, String> map) {
		String[] strs = new String[map.size()];
		map.keySet().toArray(strs);
		Arrays.sort(strs);
		StringBuffer source = new StringBuffer();
		for (String str : strs) {
			source.append(str + "=" + map.get(str) + "&");
		}
		String bigstr = source.substring(0, source.length() - 1);
		return bigstr;

	}

	// RSA签名
	public static String sign(String privateKey, String plainText) {
		try {
			byte[] keyBytes = Base64Utils.decodeFromString(privateKey);
			PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(keyBytes);
			KeyFactory keyf = KeyFactory.getInstance("RSA");
			PrivateKey prikey = keyf.generatePrivate(priPKCS8);
			Signature signet = java.security.Signature.getInstance("MD5withRSA");
			signet.initSign(prikey);
			signet.update(plainText.getBytes());
			return Base64Utils.encodeToString(signet.sign());
		} catch (java.lang.Exception e) {
			System.out.println("签名失败");
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * RSA公钥验证
	 * 
	 * @param publickey:公钥
	 * @param hexSigned：签名信息
	 * @param toSign：待签名明文
	 * @return
	 */
	public static boolean verifySignature(String publickey, String hexSigned, String plainText) {
		try {
			PublicKey publicKey = loadPublicKey(publickey);
			Signature signetCheck = Signature.getInstance("MD5withRSA");
			signetCheck.initVerify(publicKey);
			signetCheck.update(plainText.getBytes());
			if (signetCheck.verify(Base64Utils.decodeFromString(hexSigned))) {
				return true;
			}
			return false;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	public static PublicKey loadPublicKey(String publicKeyStr) throws Exception {
		try {
			byte[] buffer = Base64Utils.decodeFromString(publicKeyStr);
			KeyFactory keyFactory = KeyFactory.getInstance(RSA);
			X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
			return (RSAPublicKey) keyFactory.generatePublic(keySpec);
		} catch (NoSuchAlgorithmException e) {
			throw new Exception("无此算法");
		} catch (InvalidKeySpecException e) {
			throw new Exception("公钥非法");
		} catch (NullPointerException e) {
			throw new Exception("公钥数据为空");
		}
	}
	
	public static void main(String[] args) {
//		Map<String,String> params = new HashMap<String, String>();
//		params.put("orgId", "000001");
//		params.put("account", "13261568767");
//		String plainText = assmeblyPlainText(params);
//		System.out.println(plainText);
		//RSA签名,RSA密钥对请自行使用openssl生成
		//String sign = sign(privateKey, plainText);
		//验签
		//boolean flag = verifySignature(publickey,hexSigned,plainText);
		String merinfo = "123456:13201868440";
		System.out.println("http://localhost:8080/xxxx/oneqrcode/"+Base64Utils.encodeToString(merinfo.getBytes()));
	}
}
